package pkg

import (
	"bcb-cc-observ/pkg/config"
	"bcb-cc-observ/pkg/summary"

	"github.com/gogf/gf/frame/g"
	ledgerApi "github.com/hyperledger/fabric-sdk-go/pkg/client/ledger"
	contextApi "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context"
	"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
	fabsdkApi "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
)

type S_Network struct {
	FabSdk   *fabsdkApi.FabricSDK
	OrgAdmin string
	OrgName  string
	PeerUrl  string
}

func NewNetworkByContext(configContext, orgAdmin, orgName, peerUrl string) (*S_Network, error) {
	var sdk *fabsdkApi.FabricSDK
	configopt := config.FromContext(configContext)
	sdk, err := fabsdk.New(configopt)
	if err != nil {
		g.Log().Errorf("fabsdk 初始化失败, %v", err)
		return nil, err
	}
	//defer sdk.Close()

	var s S_Network
	s.FabSdk = sdk
	s.OrgAdmin = orgAdmin
	s.OrgName = orgName
	s.PeerUrl = peerUrl

	return &s, nil
}

func NewNetwork(configfile, orgAdmin, orgName, peerUrl string) (*S_Network, error) {
	var sdk *fabsdkApi.FabricSDK
	configopt := config.FromFile(configfile)
	sdk, err := fabsdk.New(configopt)
	if err != nil {
		g.Log().Errorf("fabsdk 初始化失败, %v", err)
		return nil, err
	}
	//defer sdk.Close()

	var s S_Network
	s.FabSdk = sdk
	s.OrgAdmin = orgAdmin
	s.OrgName = orgName
	s.PeerUrl = peerUrl

	return &s, nil
}

func (s *S_Network) Network_Close() {
	s.FabSdk.Close()
}

func (s *S_Network) GetChannels() ([]string, error) {
	return summary.GetChannels(s.FabSdk, s.OrgAdmin, s.OrgName, s.PeerUrl)
}

func (s *S_Network) GetLedger(channelid, userid, orgid string) (*ledgerApi.Client, error) {
	var fabricLedger *ledgerApi.Client
	channelProvider := s.getChannelContext(channelid, userid, orgid)
	fabricLedger, err := s.getLedger(channelProvider)
	if err != nil {
		return nil, err
	}
	return fabricLedger, nil
}

func (s *S_Network) getChannelContext(channelid, userid, orgid string) contextApi.ChannelProvider {
	var options_user fabsdkApi.ContextOption
	var options_org fabsdkApi.ContextOption

	options_user = fabsdkApi.WithUser(userid)
	options_org = fabsdkApi.WithOrg(orgid)
	channelContext := s.FabSdk.ChannelContext(channelid, options_user, options_org)
	return channelContext
}
func (s *S_Network) getLedger(channelContext contextApi.ChannelProvider) (*ledgerApi.Client, error) {
	fabricLedger, err := ledgerApi.New(channelContext)
	if err != nil {
		return nil, err
	}
	return fabricLedger, nil
}
